classdef dotsThePlayablesManager < dotsAllRemoteObjectManagers
    % @class dotsThePlayablesManager
    % @details
    % Manage objects that play sounds.
    %
    % @ingroup playable
    
    methods (Access=private)
        % Constructor is private.
        % @details
        % dotsThePlayablesManager is a singleton object, so its constructor
        % is not accessible.  Use dotsThePlayablesManager.theObject() to
        % access the current instance.
        function self = dotsThePlayablesManager(varargin)
            dotsTheMachineConfiguration.applySettingsToObject(self, true);
            self.set(varargin{:});
            self.initialize;
        end
    end
    
    methods (Static=true)
        % Access the current instance.
        function obj = theObject(varargin)
            persistent self
            if isempty(self) || ~isvalid(self)
                constructor = str2func(mfilename);
                self = feval(constructor, varargin{:});
            else
                self.set(varargin{:});
            end
            obj = self;
        end
        
        % Restore the current instance to a fresh state.
        function reset(varargin)
            factory = str2func([mfilename, '.theObject']);
            self = feval(factory, varargin{:});
            self.initialize;
        end
        
        % Launch a graphical interface to view managed dotsPlayable
        % objects.
        function g = gui
            self = dotsThePlayablesManager.theObject;
            g = self.managedObjects.gui;
        end
    end
    
    methods
        % Invoke mayPlayNow() for a playable, on client or server.
        % @param playable one of the dotsPlayable objects in
        % managedObjects.
        % @details
        % Invokes mayPlayNow() for the given @a playable.  If in
        % clientMode, requests that the server counterpart invokes
        % mayPlayNow(), instead.
        % @details
        % Returns the clockFunction timestamp taken just before invoking
        % mayPlayNow().
        function when = mayPlayPlayable(self, playable)
            if self.clientMode && self.mayRequestTransaction;
                self.requestTransaction(playable, 'lastPlayTime', true, ...
                    'mayPlayPlayable', {});
                
            else
                when = feval(self.clockFunction);
                playable.lastPlayTime = when;
                playable.mayPlayNow;
            end
        end
    end
end